bitkeeper revision 1.109 (3e677d37B9PCxHLX7a1Iufrz4eSUqA)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Thu, 6 Mar 2003 16:54:15 +0000 (16:54 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Thu, 6 Mar 2003 16:54:15 +0000 (16:54 +0000)
Manual merge of SMH + ACH worlds.

1  2 
.rootkeys
xen/drivers/block/xen_block.c
xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile
xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c

diff --cc .rootkeys
index d4cb1b135394ea6caa061bf551a693f43718dd27,f129d8995786e2807ac1f2ceab765e505edcd5f5..b73a0368cb248490c7dae1b59ab09cacd9195524
+++ b/.rootkeys
  3ddb79be04dyXzyXqDbMRS_1funwXQ xen/drivers/block/blkpg.c
  3ddb79beME_0abStePF6fU8XLuQnWw xen/drivers/block/elevator.c
  3ddb79beNQVrdGyoI4njXhgAjD6a4A xen/drivers/block/genhd.c
+ 3e677183FxihZVsJDCnvV2S0-FEZyA xen/drivers/block/grok.c
  3ddb79beyWwLRP_BiM2t1JKgr_plEw xen/drivers/block/ll_rw_blk.c
  3e4a8cb7RhubVgsPwO7cK0pgAN8WCQ xen/drivers/block/xen_block.c
 +3e5d129asHNyZOjBKTkqs-9AFzxemA xen/drivers/block/xen_segment.c
  3e4a8cb7alzQCDKS7MlioPoHBKYkdQ xen/drivers/char/Makefile
  3e4a8cb7WmiYdC-ASGiCSG_CL8vsqg xen/drivers/char/xen_kbd.c
  3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/xen_serial.c
  3e5a4e65iHEuC5sjFhj42XALYbLVRw xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile
  3e5a4e65pP5spJErBW69pJxSSdK9RA xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c
  3e5a4e65GtI9JZRAjuRdXaxt_4ohyQ xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c
+ 3e677190SjkzJIvFifRVeYpIZOCtYA xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_ide.c
+ 3e677193nOKKTLJzcAu4SYdbZaia8g xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_scsi.c
 +3e676eb5RXnHzSHgA1BvM0B1aIm4qg xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment.c
 +3e5d129aDldt6geU2-2SzBae34sQzg xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_segment_proc.c
  3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/console/Makefile
  3e5a4e651TH-SXHoufurnWjgl5bfOA xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/console/console.c
  3e5a4e656nfFISThfbyXQOA6HN6YHw xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/Makefile
index 0e6a82ccc332de32d14e8d3942da6de42adc2c52,f73f647fc49a3f4b05fb404844157e85dc8e13b2..a0e3d51059a2d6a841b026ac99dc3e4e2149a54d
@@@ -238,56 -220,23 +238,60 @@@ static void dispatch_debug_block_io(str
      DPRINTK("dispatch_debug_block_io: unimplemented\n"); 
  }
  
 -static void dispatch_probe_block_io(struct task_struct *p, int index)
 +static void dispatch_create_segment(struct task_struct *p, int index)
  {
-   blk_ring_t *blk_ring = p->blk_ring_base;
-   xv_disk_t *xvd;
-   int result;
-   if (p->domain != 0)
-   {
-     printk (KERN_ALERT "dispatch_create_segment called by dom%d\n", p->domain);
-     make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_SEG_CREATE, 1); 
-     return;
-   }
 -    extern void ide_probe_devices(xen_disk_info_t *xdi);
 -    extern void scsi_probe_devices(xen_disk_info_t *xdi);
++    blk_ring_t *blk_ring = p->blk_ring_base;
++    xv_disk_t *xvd;
++    int result;
++
++    if (p->domain != 0)
++    {
++        DPRINTK("dispatch_create_segment called by dom%d\n", p->domain);
++        make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_SEG_CREATE, 1); 
++        return;
++    }
 +
-   xvd = phys_to_virt((unsigned long)blk_ring->ring[index].req.buffer);    
-   result = xen_segment_create(xvd);
++    xvd = phys_to_virt((unsigned long)blk_ring->ring[index].req.buffer);    
++    result = xen_segment_create(xvd);
 +
-   make_response(p, blk_ring->ring[index].req.id, 
-               XEN_BLOCK_SEG_CREATE, result); 
-   return;
++    make_response(p, blk_ring->ring[index].req.id, 
++                  XEN_BLOCK_SEG_CREATE, result); 
++    return;
 +}
 +
 +static void dispatch_delete_segment(struct task_struct *p, int index)
 +{
 +    DPRINTK("dispatch_delete_segment: unimplemented\n"); 
 +}
 +
 +static void dispatch_probe_blk(struct task_struct *p, int index)
 +{
 +    extern void ide_probe_devices(xen_disk_info_t *xdi, int *count, 
 +                                drive_t xdrives[]);
++    extern void scsi_probe_devices(xen_disk_info_t *xdi, int *count,
++                                   drive_t xdrives[]);
++
      blk_ring_t *blk_ring = p->blk_ring_base;
      xen_disk_info_t *xdi;
  
      xdi = phys_to_virt((unsigned long)blk_ring->ring[index].req.buffer);    
 -    /* 
 -    ** SMH: by convention we first probe IDE, then SCSI; the latter
 -    ** apppends per-device info to the end of the xdi structure. 
 -    */
 -    ide_probe_devices(xdi);
 -    scsi_probe_devices(xdi); 
-     /* scsi_probe_devices(xdi, &num_xdrives, xdrives); */          /* future */
 +    ide_probe_devices(xdi, &num_xdrives, xdrives);
++    scsi_probe_devices(xdi, &num_xdrives, xdrives);
 +
 +    make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_BLK, 0);
 +}
 +
 +static void dispatch_probe_seg(struct task_struct *p, int index)
 +{
 +    extern void xen_segment_probe(xen_disk_info_t *xdi, int *count);
 +    blk_ring_t *blk_ring = p->blk_ring_base;
 +    xen_disk_info_t *xdi;
 +
 +    xdi = phys_to_virt((unsigned long)blk_ring->ring[index].req.buffer);    
 +    xen_segment_probe(xdi, &num_xdrives);
  
 -    make_response(p, blk_ring->ring[index].req.id, 0);
 +    make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_SEG, 0);
  }
  
  static void dispatch_rw_block_io(struct task_struct *p, int index)
  
      /* set just the important bits of the buffer header */
      memset (bh, 0, sizeof (struct buffer_head));
-       if (xen_device == XHDA_MAJOR)            phys_device = MKDEV(IDE0_MAJOR, 0);
-       else if (xen_device == XHDB_MAJOR) phys_device = MKDEV(IDE1_MAJOR, 0);
-       else if (xen_device == XHDC_MAJOR) phys_device = MKDEV(IDE2_MAJOR, 0);
-       else if (xen_device == XHDD_MAJOR) phys_device = MKDEV(IDE3_MAJOR, 0);
-       else
-       {
-       printk (KERN_ALERT "dispatch_rw_block_io: unknown device %d\n",
-               xen_device);
-       BUG();
-       }
-       block_number = blk_ring->ring[index].req.block_number;
-       sector_number = blk_ring->ring[index].req.sector_number;
 +
 +    /* map from virtual xeno devices to physical ide & scsi devices */
 +    xen_device = blk_ring->ring[index].req.device;
 +    if (IS_XHD_MAJOR(xen_device))
 +    {
-       int s;
-       if (s = xen_segment_map_request(&phys_device, &block_number, 
-                                     &sector_number,
-                                     p, operation, xen_device,
-                                     blk_ring->ring[index].req.block_number,
-                                     blk_ring->ring[index].req.sector_number))
-       {
-       printk ("dispatch_rw_block_io: xen_segment_map_request status: %d\n",
-               s);
-       goto bad_descriptor;
-       }
++        if (xen_device == XHDA_MAJOR)          phys_device = MKDEV(IDE0_MAJOR, 0);
++        else if (xen_device == XHDB_MAJOR) phys_device = MKDEV(IDE1_MAJOR, 0);
++        else if (xen_device == XHDC_MAJOR) phys_device = MKDEV(IDE2_MAJOR, 0);
++        else if (xen_device == XHDD_MAJOR) phys_device = MKDEV(IDE3_MAJOR, 0);
++        else
++        {
++            printk(KERN_ALERT "dispatch_rw_block_io: unknown device %d\n",
++                   xen_device);
++            BUG();
++        }
++
++        block_number = blk_ring->ring[index].req.block_number;
++        sector_number = blk_ring->ring[index].req.sector_number;
 +    }
 +    else if (IS_VHD_MAJOR(xen_device))
 +    {
-       printk (KERN_ALERT "dispatch_rw_block_io: unknown device %d\n",
-             xen_device);
-       BUG();
++        int s;
++        if (s = xen_segment_map_request(&phys_device, &block_number, 
++                                        &sector_number,
++                                        p, operation, xen_device,
++                                        blk_ring->ring[index].req.block_number,
++                                        blk_ring->ring[index].req.sector_number))
++        {
++            DPRINTK("dispatch_rw_block_io: xen_seg_map_request status: %d\n", s);
++            goto bad_descriptor;
++        }
 +    }
 +    else
 +    {
++        printk (KERN_ALERT "dispatch_rw_block_io: unknown device %d\n",
++                xen_device);
++        BUG();
 +    }
      
 -    bh->b_blocknr       = blk_ring->ring[index].req.block_number;
 +    bh->b_blocknr       = block_number;
      bh->b_size          = size;
 -    bh->b_dev           = blk_ring->ring[index].req.device; 
 -
 -    bh->b_rsector       = blk_ring->ring[index].req.sector_number;
 +    bh->b_dev           = phys_device;
 +    bh->b_rsector       = sector_number;
      bh->b_data          = phys_to_virt(buffer);
      bh->b_count.counter = 1;
      bh->b_end_io        = end_block_io_op;
      return;
  
   bad_descriptor:
-     printk (KERN_ALERT "dispatch rw blockio bad descriptor\n");
 -    make_response(p, blk_ring->ring[index].req.id, 1);
 -    return;
 -}
++    DPRINTK("dispatch rw blockio bad descriptor\n");
 +    make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_READ, 1);
-     return;
 +} 
  
  
  
@@@ -468,23 -373,8 +470,23 @@@ static void make_response(struct task_s
  
  static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs) 
  {
-   struct task_struct *p;
-   blk_ring_t *blk_ring ;
++    struct task_struct *p;
++    blk_ring_t *blk_ring ;
 +
-   printk("Dumping block queue stats: nr_pending = %d\n",
-        atomic_read(&nr_pending));
+     printk("Dumping block queue stats: nr_pending = %d\n",
+            atomic_read(&nr_pending));
 +
-   p = current->next_task;
-   do
-   {
-     printk (KERN_ALERT "Domain: %d\n", p->domain);
-     blk_ring = p->blk_ring_base;
++    p = current->next_task;
++    do
++    {
++        printk (KERN_ALERT "Domain: %d\n", p->domain);
++        blk_ring = p->blk_ring_base;
 +
-     printk("  req_prod:%d, resp_prod:%d, req_cons:%d\n",
-          blk_ring->req_prod, blk_ring->resp_prod, p->blk_req_cons);
++        printk("  req_prod:%d, resp_prod:%d, req_cons:%d\n",
++               blk_ring->req_prod, blk_ring->resp_prod, p->blk_req_cons);
 +
-     p = p->next_task;
-   } while (p != current);
++        p = p->next_task;
++    } while (p != current);
  }
  
  /* Start-of-day initialisation for a new domain. */
index 594aab25b89ece5e053ab38f7f34f299e21ac6c5,56413ed106cde1155d20e590395b607dec7d0662..fd6b63f51e056cf847caa1402b540e5162fe198b
@@@ -1,3 -1,3 +1,4 @@@
  O_TARGET := blk.o
- obj-y := xl_block.o xl_segment.o xl_segment_proc.o xl_block_test.o
 -obj-y := xl_block.o xl_ide.o xl_scsi.o xl_block_test.o
++obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o 
++obj-y += xl_segment_proc.o xl_block_test.o
  include $(TOPDIR)/Rules.make
index bc87e7eb7b16cc282f869f3d8865383f1fac0701,3130280c57f8a7805066e36f93a33e5c34a450c7..af270f1aa1046e3dd202adfebc7f62c33ab701c9
  #include <asm/hypervisor-ifs/block.h>
  #include <asm/hypervisor-ifs/hypervisor-if.h>
  #include <asm/io.h>
 +#include <asm/atomic.h>
  #include <asm/uaccess.h>
  
- #define MAJOR_NR XLBLK_MAJOR   /* force defns in blk.h, must precede include */
- static int xlblk_major = XLBLK_MAJOR;
  #include <linux/blk.h>
  
  /* Copied from linux/ide.h */
  typedef unsigned char byte; 
  
- #define XLBLK_MAX 32 /* Maximum minor devices we support */
- #define XLBLK_MAJOR_NAME "xhd"
- #define IDE_PARTN_BITS 6                           /* from ide.h::PARTN_BITS */
- #define IDE_PARTN_MASK ((1<<IDE_PARTN_BITS)-1)     /* from ide.h::PARTN_MASK */
- static int xlblk_blk_size[XLBLK_MAX];
- static int xlblk_blksize_size[XLBLK_MAX];
- static int xlblk_read_ahead; 
- static int xlblk_hardsect_size[XLBLK_MAX];
- static int xlblk_max_sectors[XLBLK_MAX];
 -
+ extern int  xlide_init(int xidx, int idx); 
+ extern int  xlide_hwsect(int minor); 
+ extern void xlide_cleanup(void); 
+ extern int  xlscsi_init(int xidx, int idx);
+ extern int  xlscsi_hwsect(int minor); 
+ extern void xlscsi_cleanup(void); 
+ static int nide = 0;    // number of IDE devices we have 
+ static int nscsi = 0;   // number of SCSI devices we have 
+ #define XLBLK_MAX 32 /* XXX SMH: this the max of XLIDE_MAX and XLSCSI_MAX */
  
  #define XLBLK_RESPONSE_IRQ _EVENT_BLK_RESP
 +
  #define DEBUG_IRQ    _EVENT_DEBUG 
  
  #if 0
  
  static blk_ring_t *blk_ring;
  static unsigned int resp_cons; /* Response consumer for comms ring. */
 -xen_disk_info_t xen_disk_info;
 -
 -int hypervisor_request(void *         id,
 -                       int            operation,
 -                       char *         buffer,
 -                       unsigned long  block_number,
 -                       unsigned short block_size,
 -                       kdev_t         device);
 +static xen_disk_info_t xlblk_disk_info;
 +atomic_t xlblk_control_count;
  
 +void xlblk_ide_register_disk(int, unsigned long);
 +void do_xlseg_requestX (request_queue_t *rq);
 +int hypervisor_request(void *          id,
 +                       int             operation,
 +                       char *          buffer,
 +                       unsigned long   block_number,
 +                       unsigned short  block_size,
 +                       kdev_t          device,
 +                     struct gendisk *gd);
  
  /* ------------------------------------------------------------------------
   */
  
@@@ -102,41 -169,38 +173,57 @@@ int xenolinux_block_ioctl(struct inode 
      DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, minor: 0x%x\n",
                    command, (long) argument, minor_dev); 
    
+     gd = xldev_to_gendisk(inode->i_rdev, &type); 
+     part = &gd->part[minor_dev]; 
      switch (command)
      {
-     case BLKGETSIZE:                                             /* get size */
-         DPRINTK_IOCTL("   BLKGETSIZE: %x %lx\n", BLKGETSIZE, 
-                       (long) xlblk_disk_info.disks[0].capacity); 
-       return put_user(xlblk_disk_info.disks[0].capacity, 
-                       (unsigned long *) argument);
+     case BLKGETSIZE:
+         DPRINTK_IOCTL("   BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects); 
+       return put_user(part->nr_sects, (unsigned long *) argument);
  
 -    case BLKRRPART:
 +    case BLKRRPART:                               /* re-read partition table */
          DPRINTK_IOCTL("   BLKRRPART: %x\n", BLKRRPART); 
        break;
  
-     case BLKBSZGET:                                        /* get block size */
-         DPRINTK_IOCTL("   BLKBSZGET: %x\n", BLKBSZGET);
-       break;
+     case BLKSSZGET:
+       switch(type) {
+       case 1: 
+           DPRINTK_IOCTL("   BLKSSZGET: %x 0x%x\n", BLKSSZGET, 
+                         xlide_hwsect(minor_dev));
+           return xlide_hwsect(minor_dev); 
+           break; 
+       case 2: 
+           DPRINTK_IOCTL("   BLKSSZGET: %x 0x%x\n", BLKSSZGET,
+                         xlscsi_hwsect(minor_dev));
+           return xlscsi_hwsect(minor_dev); 
+           break; 
+       default: 
+           printk("BLKSSZGET ioctl() on bogus type %d disk!\n", type); 
+           return 0; 
+       }
 +
 +    case BLKBSZSET:                                        /* set block size */
 +        DPRINTK_IOCTL("   BLKBSZSET: %x\n", BLKBSZSET);
 +      break;
 +
 +    case BLKRASET:                                         /* set read-ahead */
 +        DPRINTK_IOCTL("   BLKRASET: %x\n", BLKRASET);
 +      break;
 +
 +    case BLKRAGET:                                         /* get read-ahead */
 +        DPRINTK_IOCTL("   BLKRAFET: %x\n", BLKRAGET);
 +      break;
 +
 +    case BLKSSZGET:                                       /* get sector size */
 +        DPRINTK_IOCTL("   BLKSSZGET: %x 0x%x\n", BLKSSZGET,
 +                      xlblk_hardsect_size[minor_dev]);
 +      return xlblk_hardsect_size[minor_dev]; 
 +
      case HDIO_GETGEO:
 +        /* note: these values are complete garbage */
          DPRINTK_IOCTL("   HDIO_GETGEO: %x\n", HDIO_GETGEO);
        if (!argument) return -EINVAL;
        if (put_user(0x00,  (unsigned long *) &geo->start)) return -EFAULT;
@@@ -224,30 -284,13 +311,13 @@@ int hypervisor_request(void *          
  
      case XEN_BLOCK_READ:
      case XEN_BLOCK_WRITE:
-         /* only accept requests for xhd and vhd devices */
-       if (!IS_XHD_MAJOR(MAJOR(device)) && !IS_VHD_MAJOR(MAJOR(device)))
-           panic("error: xl_block::hypervisor_request: "
-                   "unknown device [0x%x]\n", device);
-       phys_device = MAJOR(device);
--
-       /* Compute real buffer location on disk.
-        * note: gd will be null when we read the partition table.
-        */
+         phys_device =  xldev_to_physdev(device); 
 -
++      if (!IS_XHD_MAJOR(MAJOR(device)))
++            phys_device = MAJOR(device);
+       /* Compute real buffer location on disk */
        sector_number = block_number;
-       if ( gd != NULL )
-       {
-         sector_number += gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect;
-       }
-       /*
-       if (IS_VHD_MAJOR(MAJOR(device)))
-       {
-         printk (KERN_ALERT "%lx + %lx = %lx (%x)\n",
-                 block_number,
-                 gd->part[MINOR(device)&IDE_PARTN_MASK].start_sect,
-                 sector_number, device);
-       }
-       */
+       gd = xldev_to_gendisk(device, NULL); 
+       sector_number += gd->part[MINOR(device)].start_sect;
          break;
  
      default:
@@@ -383,10 -411,17 +454,18 @@@ static void xlblk_response_int(int irq
      resp_cons = i;
  
      /* KAF: We can push work down at this point. We have the lock. */
-     /* aho: okay, so this is a bit of a hack.  we'll kick every queue... */
-     do_xlblk_request(BLK_DEFAULT_QUEUE(XLBLK_MAJOR));
-     do_xlseg_requestX(BLK_DEFAULT_QUEUE(XLSEG_MAJOR));
-     
+     for (i = 0; i < xen_disk_info.count; i++) {
+       /*
+       ** XXX SMH: this is pretty broken ... 
+       **     a) should really only kick devs w/ outstanding work 
+       **     b) should cover /all/ devs, not just first IDE & SCSI
+       ** KAF will fix this I'm sure. 
+       */
+       do_xlblk_request(BLK_DEFAULT_QUEUE(IDE0_MAJOR));
+       do_xlblk_request(BLK_DEFAULT_QUEUE(SCSI_DISK0_MAJOR));
++        do_xlseg_requestX(BLK_DEFAULT_QUEUE(XLSEG_MAJOR));
+     }
      spin_unlock_irqrestore(&io_request_lock, flags);
  }
  
@@@ -419,143 -449,57 +498,54 @@@ int __init xlblk_init(void
          BUG();
      HYPERVISOR_block_io_op();
      while ( blk_ring->resp_prod != 1 ) barrier();
-     printk (KERN_ALERT "xhd block device probe:\n");
 -
 -    for ( i = 0; i < xen_disk_info.count; i++ )
 +    for ( i = 0; i < xlblk_disk_info.count; i++ )
      { 
+       /* 
+       ** SMH: initialize all the disks we found; this is complicated a 
+       ** bit by the fact that we have both IDE and SCSI disks underneath 
+       */
        printk (KERN_ALERT "  %2d: type: %d, capacity: %ld\n",
 -              i, xen_disk_info.disks[i].type, 
 -              xen_disk_info.disks[i].capacity);
 +              i, xlblk_disk_info.disks[i].type, 
 +              xlblk_disk_info.disks[i].capacity);
+       
+       switch(xen_disk_info.disks[i].type) { 
+       case 1: 
+           xlide_init(i, nide++); 
+           break; 
+       case 2: 
+           xlscsi_init(i, nscsi++); 
+           break; 
+       default: 
+           printk("Unknown Xen disk type %d\n", xen_disk_info.disks[i].type);
+           break; 
+       }
 -
      }
-     
-     SET_MODULE_OWNER(&xenolinux_block_fops);
-     result = register_blkdev(xlblk_major, "block", &xenolinux_block_fops);
-     if (result < 0) {
-       printk (KERN_ALERT "xenolinux block: can't get major %d\n",
-               xlblk_major);
-       return result;
-     }
-     /* initialize global arrays in drivers/block/ll_rw_block.c */
-     for (i = 0; i < XLBLK_MAX; i++) {
-       xlblk_blk_size[i]      = xlblk_disk_info.disks[0].capacity;
-       xlblk_blksize_size[i]  = 512;
-       xlblk_hardsect_size[i] = 512;
-       xlblk_max_sectors[i]   = 128;
-     }
-     xlblk_read_ahead  = 8; 
-     blk_size[xlblk_major]      = xlblk_blk_size;
-     blksize_size[xlblk_major]  = xlblk_blksize_size;
-     hardsect_size[xlblk_major] = xlblk_hardsect_size;
-     read_ahead[xlblk_major]    = xlblk_read_ahead; 
-     max_sectors[xlblk_major]   = xlblk_max_sectors;
-     blk_init_queue(BLK_DEFAULT_QUEUE(xlblk_major), do_xlblk_request);
-     /*
-      * Turn off barking 'headactive' mode. We dequeue buffer heads as
-      * soon as we pass them down to Xen.
-      */
-     blk_queue_headactive(BLK_DEFAULT_QUEUE(xlblk_major), 0);
  
-     xlblk_ide_register_disk(0, xlblk_disk_info.disks[0].capacity);
-     printk(KERN_ALERT 
-          "XenoLinux Virtual Block Device Driver installed [device: %d]\n",
-          xlblk_major);
      return 0;
  
   fail:
      return error;
  }
  
- void xlblk_ide_register_disk(int idx, unsigned long capacity)
- {
-     int units;
-     int minors;
-     struct gendisk *gd;
-     /* plagarized from ide-probe.c::init_gendisk */
-     
-     units = 2; /* from ide.h::MAX_DRIVES */
-     minors    = units * (1<<IDE_PARTN_BITS);
-     gd        = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
-     gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
-     gd->part  = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
-     memset(gd->part, 0, minors * sizeof(struct hd_struct));
-     
-     gd->major        = xlblk_major;  
-     gd->major_name   = XLBLK_MAJOR_NAME;
-     gd->minor_shift  = IDE_PARTN_BITS; 
-     gd->max_p      = 1<<IDE_PARTN_BITS;
-     gd->nr_real            = units;           
-     gd->real_devices = NULL;          
-     gd->next       = NULL;            
-     gd->fops         = &xenolinux_block_fops;
-     gd->de_arr       = kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);
-     gd->flags      = kmalloc (sizeof *gd->flags * units, GFP_KERNEL);
-     if (gd->de_arr)  
-       memset (gd->de_arr, 0, sizeof *gd->de_arr * units);
-     if (gd->flags) 
-       memset (gd->flags, 0, sizeof *gd->flags * units);
-     add_gendisk(gd);
-     xlblk_disk_info.disks[idx].gendisk = gd;
-     register_disk(gd, MKDEV(xlblk_major, 0), 1<<IDE_PARTN_BITS,
-                 &xenolinux_block_fops, capacity);
-     {
-       int loop = 0;
-       printk (KERN_ALERT "Partition Table: (capacity: %lx)\n", capacity);
-       for (loop = 0; loop < minors; loop++)
-       {
-       if (gd->part[loop].start_sect && gd->part[loop].nr_sects)
-       {
-         printk (KERN_ALERT 
-                 "  %2d: 0x%6lx %8ld    0x%6lx %7ld\n", loop,
-                 gd->part[loop].start_sect, gd->part[loop].start_sect,
-                 gd->part[loop].nr_sects, gd->part[loop].nr_sects);
-       }
-       }
-     }
-     return;
- }
--
  static void __exit xlblk_cleanup(void)
  {
-     /* CHANGE FOR MULTIQUEUE */
-     blk_cleanup_queue(BLK_DEFAULT_QUEUE(xlblk_major));
-     /* clean up global arrays */
-     read_ahead[xlblk_major] = 0;
-     if (blk_size[xlblk_major]) 
-       kfree(blk_size[xlblk_major]);
-     blk_size[xlblk_major] = NULL;
+     int i; 
  
-     if (blksize_size[xlblk_major]) 
-       kfree(blksize_size[xlblk_major]);
-     blksize_size[xlblk_major] = NULL;
+     for ( i = 0; i < xen_disk_info.count; i++ )
+     { 
+       switch(xen_disk_info.disks[i].type) { 
+       case 1: 
+           xlide_cleanup(); 
+           break; 
+       case 2: 
+           xlscsi_cleanup(); 
+           break; 
+       default: 
+           printk("Unknown Xen disk type %d\n", xen_disk_info.disks[i].type);
+           break; 
+       }
  
-     if (hardsect_size[xlblk_major]) 
-       kfree(hardsect_size[xlblk_major]);
-     hardsect_size[xlblk_major] = NULL;
-     
-     /* XXX: free each gendisk */
-     if (unregister_blkdev(xlblk_major, "block"))
-       printk(KERN_ALERT
-              "XenoLinux Virtual Block Device Driver uninstalled w/ errs\n");
-     else
-       printk(KERN_ALERT 
-              "XenoLinux Virtual Block Device Driver uninstalled\n");
+     }
  
      return;
  }